



//  #include "user_flash.h"



#ifndef __USER_FLASH_H__
#define __USER_FLASH_H__


#include "iotv30_config.h"


#include  "stdint.h"
#include  "stdio.h"
#include <stdbool.h>



#define  CCT_ID_LEN       (0x06u)




//--------相对路径-----------------------
#define CCT_APP_INSTALL_PATH        ("./")

//#define USER_FLASH_FILE_PATH        ("./user_flash.txt")
#define USER_FLASH_FILE_PATH        ("./user_data.flash")
//#define NODE_FLASH_FILE_PATH        ("./Node_data.flash")
#define  CCT_APP_FLASH_FILE_PATH       ("./cct_app.flash") 
#define  NODE_APP_FLASH_FILE_PATH       ("./Node_APP.flash")     //节点固件flash
#define  STOP_SHELL_PATH                ("./stop_app.sh")     //停止

#define CCT_APP_UPGRADE_OK_FILE_PATH     ("./cct_app_upgrade_ok.txt")

#define  STOP_SOUTH_SHELL_PATH            ("../stop_app.sh") // 停止south


#define FLASH_SECTOR_SIZE           (1024U)//1K 1024U
#define FLASH_BASE                  (0UL)
#define PAGE_SIZE            FLASH_SECTOR_SIZE


#define USER_FLASH_SIZE                     (32*1024U)       // 32k
#define CCT_APP_FLASH_SIZE                  (64*1024*1024U)   //64M 当前实际1.2M
#define NODE_APP_FLASH_SIZE                 (100*1024U)      //100k 当前实际50k

#define FLASH_SIZE                          (CCT_APP_FLASH_SIZE)  //




//#define Flash_Size           FLASH_SIZE

      
#define APP_Flash_Size      ( CCT_APP_FLASH_SIZE )    


//#define IAP_Address                   FLASH_BASE                                                                                           
#define APP_Address                    ( FLASH_BASE )  
#define APP_Backup_Address             ( APP_Address )  
//#define APP_Backup_Address             ( APP_Address + APP_Flash_Size)  



#define NODE_APP_Address               ( FLASH_BASE ) 
           
#define Param_Flash_Address_Start      ( FLASH_BASE  )         //数据参数flash片区            
#define Param_Flash_Address_End        ( Param_Flash_Address_Start + USER_FLASH_SIZE )    

//#endif

#define FLASH_UPDATE_DATA_PAGE                (Param_Flash_Address_Start)                       //升级标志映射地址
#define FLASH_CCT_PARAM_PAGE                  (FLASH_UPDATE_DATA_PAGE + FLASH_SECTOR_SIZE )     //集中器参数映射地址-
#define FLASH_USER_DATA_PAGE                  (FLASH_CCT_PARAM_PAGE   + FLASH_SECTOR_SIZE )     //用户数据映射地址

#define FLASH_TASK_PAGE                       (FLASH_USER_DATA_PAGE      + FLASH_SECTOR_SIZE )     //定时任务数据-
#define RESERVE_FLASH_TASK_PAGE               (FLASH_TASK_PAGE           + FLASH_SECTOR_SIZE )     //定时任务备份数据
#define FLASH_NODE_PAGE1_ADR                  (RESERVE_FLASH_TASK_PAGE   + 4*FLASH_SECTOR_SIZE )    //节点数据




#define FLASH_NODE_HEAD_ADR             FLASH_NODE_PAGE1_ADR           // FLASH HEAD 帧头 标记 的偏移地址
#define FLASH_NODE_TOTAL_ADR           (FLASH_NODE_PAGE1_ADR + 2)      // 配置节点总数 的偏移地址
#define FLASH_NODE_START_ADR           (FLASH_NODE_PAGE1_ADR + 4)      //存储数据的偏移地址






#define   FLASH_FIRST_WR               (0xA9U)

#define   FLASH_CCT_PARAM_FIRST_WR     (0xA9U)
#define   FLASH_USER_FIRST_WR          (0xA9U)
#define   FLASH_PILE_PARAM_FIRST_WR    (0xA8U)

#define   FLASH_UPDATE_FIRST_WR        (0xA8U)


//const uint8_t CCT_SW_VerHex[4]={0x00,0x00,0x04,0x03};  //软件版本号FW_Version
#define FLASH_WRITE_FLAG       (0X0403U)
#define FLASH_VALID_FLAG1      (0X0403U)    //
#define FLASH_VALID_FLAG2      (0X55AAu) 





#pragma pack(1)



#define   UPDATE_DATA_BUF_MAX     (64U)

typedef	 union 
{
		uint8_t  Buffer[UPDATE_DATA_BUF_MAX];
		struct         
		{					
			    uint8_t  First;               //首次上电  	
			
				uint8_t  StartFlag;           //开始升级标记
				uint8_t  DoneFlag;            //升级完成标记			
				uint8_t  Cnt;                 //升级计数

								
		} Reg;
	
} UpdateData_u;





typedef		struct         
{		
    uint8_t local_mac[6];	    //本地MAC地址
    uint8_t local_ip[4];		//本地IP地址
    uint8_t subnet[4];			//子网掩码
    uint8_t gateway[4];			//网关	
    uint8_t dns_server[4];		//DNS服务器地址
	
//    uint8_t server_ip[4];		//服务器IP地址 
	
	  uint16_t local_port;	    //本地端口号
//    uint16_t server_port;		//服务器端口号  
	
			
}  EthParam_st;

#pragma pack()
			

 
    

//----测试数据------

#define   USER_DATA_BUF_MAX     (128U)

typedef	 union 
{
		uint8_t  Buffer[USER_DATA_BUF_MAX];
		struct         
		{					
			uint8_t     First;             //首次上电  	
					
            EthParam_st   EthParam;
            uint16_t   ucSumOfNode ;  //--部署节点数量----g_ucSumOfNode

			uint32_t   RunTimeMin;     //运行时长--单位min	

		} Reg;
	
}  UserData_u;


extern  UserData_u    UserData;



#pragma pack()



extern    uint8_t   ucUserDataSaveFlag;  
extern    uint8_t   ucUpdateDataSaveFlag;  

extern volatile uint8_t  gucPowerDownIntFlag ;


extern  UpdateData_u  UpdateData;

//extern EthString_st    EthString;


//----需要放在------Param_Init( )--之后-----------------
void UserFlash_Init(void);
void Read_EthParam(void);
void UserFlash_Create(void);
void ResetUpdateFlag(void);
void SetUpdateFlag(void);

void UserData_SaveEnable(void);	
void UpdateData_SaveEnable(void);


void UserFlash_SaveProcess(void);

void EthParam_Update(void);


FILE*  FLASH_Unlock(void);
void   FLASH_Lock(FILE* pFile);


/**
 *  @brief //以（读写）形式打开文件  
 *  @param [in] file_name----文件名---不包括路径----//文件名不能超过100Bs---路径名最大155Bs
 *  @param [out] null
 *
 *  @return FILE*
 *   != NULL -- 打开文件成功
 *   = NULL -- 打开文件失败
 */
FILE*   File_Unlock(const char *file_name);

#define File_Lock   FLASH_Lock





/**
 *  @brief 判断文件是否存在--
 *  @param [in] file_name----文件名---不包括路径----
 *  @param [out] null
 *
 *  @return
 *   = true -- 文件存在
 *   = false - 文件不存在
 */

bool  File_Test(const char *file_name);




//返回值0--表示写flash失败，1表示成功---内部包含页擦除功能---
uint8_t WriteDataToFlash_8Bits(FILE *fp, uint8_t* data,uint32_t dst_flash_addr,uint16_t data_len) ;

//返回值0--表示写flash失败，非0表示成功-------内部包含页擦除功能----
uint8_t WriteDataToFlash_16Bits( FILE *fp, uint16_t* data,uint32_t dst_flash_addr,uint16_t data_len);

//返回值0--表示写flash失败，非0表示成功-------内部包含页擦除功能----
uint8_t WriteDataToFlash_32Bits( FILE *fp, uint32_t* data,uint32_t dst_flash_addr,uint16_t data_len);


//返回值0--表示写flash失败，1表示成功-----需要在外部先擦除，才能调用该函数------
uint8_t  ProgramDataToFlash_8Bits(FILE *fp, uint8_t* data,uint32_t dst_flash_addr,uint16_t data_len);

//返回值0--表示读flash失败，非0表示成功---
uint8_t ReadDataFromFlash_8Bits(FILE *fp, uint8_t *data, uint32_t flash_addr, uint16_t len);


//返回值0--表示写flash失败，非0表示成功-------内部包含页擦除功能----
uint8_t Flash_EraseSector(FILE* pFile,uint32_t u32Addr);   

#define   FLASH_ErasePage     Flash_EraseSector



unsigned char FlashWriteCheck(FILE *fp, unsigned long ulFlashAdr);

void WriteHalfWordToFlash(FILE *fp, uint16_t  uiWord, unsigned long ulFlashAdr);
void WriteWordToFlash(FILE *fp, uint32_t  uWord, unsigned long ulFlashAdr);

 uint32_t  Flash_GetAppSize(void);
 

#endif     //__USER_FLASH_H__























